package com.zidongxiangxi.rabbit.producer.support;

import com.alibaba.fastjson.JSON;
import com.zidongxiangxi.rabbit.core.exception.ReliableRabbitException;
import com.zidongxiangxi.rabbit.producer.entity.RabbitCorrelationId;
import com.zidongxiangxi.rabbit.producer.manager.ProducerManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.util.StringUtils;

import java.util.Objects;

/**
 * RabbitMq消息发送确认
 *
 * @author chenxudong
 * @date 2020/11/07
 */
public class RabbitConfirmCallback implements RabbitTemplate.ConfirmCallback {
	private final Logger logger = LoggerFactory.getLogger(RabbitConfirmCallback.class);
	private final ProducerManager producerManager;

	public RabbitConfirmCallback(ProducerManager producerManager) {
		this.producerManager = producerManager;
	}

	@Override
	public void confirm(CorrelationData correlationData, boolean ack, String cause) {
		try {
			if (Objects.nonNull(correlationData) && !StringUtils.isEmpty(correlationData.getId())) {
				String correlationDataJsonString = JSON.toJSONString(correlationData);
				logger.debug("receive publish confirm, correlationData: {}", correlationDataJsonString);
				RabbitCorrelationId id = RabbitCorrelationId.parseRabbitCorrelationId(correlationData.getId());
				if (Objects.isNull(id)) {
					logger.info("fail to parse correlationId:{}", correlationData.getId());
					return;
				}
				if (ack) {
					logger.debug("success to send message, correlationId:{}", correlationData.getId());
					producerManager.deleteMq(id.getApplication(), id.getMessageId());
				} else {
					throw new ReliableRabbitException("MQ发送失败, correlationId:" + correlationData.getId());
				}
			} else {
				if (ack) {
					logger.warn("MQ发送成功，但是缺少correlationId");
				} else {
					throw new ReliableRabbitException("MQ发送失败， 而且缺少correlationId");
				}
			}
		} catch (ReliableRabbitException e) {
			logger.warn("MQ发送异常", e);
		}
	}
}
